package com.tsfyun.scm.service.impl.customer;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.lang.Snowflake;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.google.common.collect.Lists;
import com.tsfyun.common.base.config.OrikaBeanMapper;
import com.tsfyun.common.base.exception.ServiceException;
import com.tsfyun.common.base.extension.OrderItem;
import com.tsfyun.common.base.security.SecurityUtil;
import com.tsfyun.common.base.util.StringUtils;
import com.tsfyun.common.base.util.TsfPreconditions;
import com.tsfyun.scm.dto.customer.CustomerAbroadDeliveryInfoDTO;
import com.tsfyun.scm.dto.customer.client.ClientCustomerAbroadDeliveryInfoQTO;
import com.tsfyun.scm.entity.customer.Customer;
import com.tsfyun.scm.entity.customer.CustomerAbroadDeliveryInfo;
import com.tsfyun.scm.mapper.customer.CustomerAbroadDeliveryInfoMapper;
import com.tsfyun.scm.service.customer.ICustomerAbroadDeliveryInfoService;
import com.tsfyun.common.base.extension.ServiceImpl;
import com.tsfyun.scm.service.customer.ICustomerService;
import com.tsfyun.scm.util.PermissionUtil;
import com.tsfyun.scm.util.TsfWeekendSqls;
import com.tsfyun.scm.vo.customer.CustomerAbroadDeliveryInfoVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import tk.mybatis.mapper.entity.Example;
import tk.mybatis.mapper.weekend.WeekendSqls;

import java.util.*;
import java.util.stream.Collectors;

/**
 * <p>
 * 客户境外送货地址 服务实现类
 * </p>
 *
 *
 * @since 2021-09-16
 */
@Service
public class CustomerAbroadDeliveryInfoServiceImpl extends ServiceImpl<CustomerAbroadDeliveryInfo> implements ICustomerAbroadDeliveryInfoService {

    @Autowired
    private ICustomerService customerService;

    @Autowired
    private CustomerAbroadDeliveryInfoMapper customerAbroadDeliveryInfoMapper;

    @Autowired
    private OrikaBeanMapper beanMapper;

    @Autowired
    private Snowflake snowflake;

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void add(CustomerAbroadDeliveryInfoDTO dto, boolean handleDefault) {
        TsfPreconditions.checkArgument(Objects.nonNull(dto.getCustomerId()),new ServiceException("请选择客户"));
        Customer customer = customerService.getById(dto.getCustomerId());
        TsfPreconditions.checkArgument(Objects.nonNull(customer),new ServiceException("您选择的客户信息不存在"));
        CustomerAbroadDeliveryInfo customerDeliveryInfo = beanMapper.map(dto,CustomerAbroadDeliveryInfo.class);
        if(handleDefault) {
            //默认地址信息处理
            if (Objects.equals(Boolean.TRUE, customerDeliveryInfo.getIsDefault())) {
                //需要设置为默认地址，需要取消之前设置的默认地址
                handleOldDefault(customer.getId());
            }
        }
        super.saveNonNull(customerDeliveryInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void edit(CustomerAbroadDeliveryInfoDTO dto,boolean handleDefault) {
        TsfPreconditions.checkArgument(Objects.nonNull(dto.getCustomerId()),new ServiceException("请选择客户"));
        CustomerAbroadDeliveryInfo oldCustomerDeliveryInfo = super.getById(dto.getId());
        TsfPreconditions.checkArgument(Objects.nonNull(oldCustomerDeliveryInfo),new ServiceException("您选择的数据不存在"));
        Customer customer = customerService.getById(dto.getCustomerId());
        TsfPreconditions.checkArgument(Objects.nonNull(customer),new ServiceException("您选择的客户信息不存在"));
        CustomerAbroadDeliveryInfo customerDeliveryInfo = beanMapper.map(dto,CustomerAbroadDeliveryInfo.class);
        customerDeliveryInfo.setDateCreated(oldCustomerDeliveryInfo.getDateCreated());
        customerDeliveryInfo.setCreateBy(oldCustomerDeliveryInfo.getCreateBy());
        customerDeliveryInfo.setDisabled(Objects.equals(dto.getDisabled(),Boolean.TRUE));
        customerDeliveryInfo.setIsDefault(Objects.equals(dto.getIsDefault(),Boolean.TRUE));
        if(handleDefault) {
            //如果由非默认变为默认则需要处理之前设置的默认的
            if (!oldCustomerDeliveryInfo.getIsDefault() && customerDeliveryInfo.getIsDefault()) {
                handleOldDefault(customer.getId());
            }
            super.updateById(customerDeliveryInfo);
        }
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void saveList(Long customerId, List<CustomerAbroadDeliveryInfoDTO> dtos) {
        if(CollectionUtil.isEmpty(dtos)) {
            return;
        }
        //设置第一个启用的为默认
        Boolean isDefault = false;
        for(int i=0;i<dtos.size();i++){
            CustomerAbroadDeliveryInfoDTO dto = dtos.get(i);
            if(dto.getIsDefault() && dto.getDisabled() != true){
                isDefault=true;
            }
        }
        if(isDefault==false){
            for(int i=0;i<dtos.size();i++) {
                CustomerAbroadDeliveryInfoDTO dto = dtos.get(i);
                if (dto.getDisabled() != true) {
                    dtos.get(i).setIsDefault(Boolean.TRUE);
                }
            }
        }
        //删除客户地址信息
        removeByCustomerId(customerId);
        List<CustomerAbroadDeliveryInfo> customerDeliveryInfoList = Lists.newArrayList();
        dtos.stream().forEach(delivery ->{
            CustomerAbroadDeliveryInfo customerDeliveryInfo = new CustomerAbroadDeliveryInfo();
            customerDeliveryInfo.setId(snowflake.nextId());
            customerDeliveryInfo.setCustomerId(customerId);

            customerDeliveryInfo.setCompanyName(StringUtils.removeSpecialSymbol(delivery.getCompanyName()));
            customerDeliveryInfo.setLinkPerson(StringUtils.removeSpecialSymbol(delivery.getLinkPerson()));
            customerDeliveryInfo.setLinkTel(StringUtils.removeSpecialSymbol(delivery.getLinkTel()));
            customerDeliveryInfo.setProvinceName(StringUtils.removeSpecialSymbol(delivery.getProvinceName()));
            customerDeliveryInfo.setCityName(StringUtils.removeSpecialSymbol(delivery.getCityName()));
            customerDeliveryInfo.setAreaName(StringUtils.removeSpecialSymbol(delivery.getAreaName()));
            customerDeliveryInfo.setAddress(StringUtils.removeSpecialSymbol(delivery.getAddress()));
            customerDeliveryInfo.setDisabled(delivery.getDisabled());
            customerDeliveryInfo.setIsDefault(delivery.getIsDefault());
            //customerDeliveryInfo.setDateCreated(LocalDateTime.now());
            //customerDeliveryInfo.setCreateBy(SecurityUtil.getCurrentPersonIdAndName());
            //customerDeliveryInfo.setDateUpdated(customerDeliveryInfo.getDateCreated());
            //customerDeliveryInfo.setUpdateBy(customerDeliveryInfo.getCreateBy());
            customerDeliveryInfoList.add(customerDeliveryInfo);
        });
        super.savaBatch(customerDeliveryInfoList);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void activeDisable(Long id) {
        CustomerAbroadDeliveryInfo customerDeliveryInfo = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(customerDeliveryInfo),new ServiceException("客户境外收货地址信息不存在"));
        customerDeliveryInfo.setDisabled(!customerDeliveryInfo.getDisabled());
        customerDeliveryInfo.setIsDefault(Boolean.FALSE);
        super.updateById(customerDeliveryInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void setDefault(Long id) {
        CustomerAbroadDeliveryInfo  customerDeliveryInfo = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(customerDeliveryInfo),new ServiceException("客户境外收货地址信息不存在"));
        Boolean currentDefault = customerDeliveryInfo.getIsDefault();
        if(Objects.equals(Boolean.TRUE,currentDefault)) {
            //以前是默认，则现在无需操作
            return;
        } else {
            //以前是非默认，现在置为默认，则需要取消以前的默认如果存在的话
            handleOldDefault(customerDeliveryInfo.getCustomerId());
            customerDeliveryInfo.setIsDefault(Boolean.TRUE);
            customerDeliveryInfo.setDisabled(Boolean.FALSE);
            super.updateById(customerDeliveryInfo);
        }
    }

    /**
     * 取消以前设置的默认地址
     * @param customerId
     */
    @Override
    public void handleOldDefault(Long customerId) {
        CustomerAbroadDeliveryInfo update = new CustomerAbroadDeliveryInfo();
        update.setIsDefault(Boolean.FALSE);
        customerAbroadDeliveryInfoMapper.updateByExampleSelective(update, Example.builder(CustomerAbroadDeliveryInfo.class).where(WeekendSqls.<CustomerAbroadDeliveryInfo>custom()
                .andEqualTo(CustomerAbroadDeliveryInfo::getCustomerId, customerId)
                .andEqualTo(CustomerAbroadDeliveryInfo::getIsDefault,Boolean.TRUE)).build());
    }

    @Override
    public List<CustomerAbroadDeliveryInfoVO> select(Long customerId) {
        CustomerAbroadDeliveryInfo condition = new CustomerAbroadDeliveryInfo();
        condition.setCustomerId(customerId);
        condition.setDisabled(Boolean.FALSE);
        List<CustomerAbroadDeliveryInfo> list = super.list(condition);
        //按是否默认排序，然后按最后修改日期排序
        if(CollectionUtil.isNotEmpty(list)) {
            //先按是否默认排序然后按修改时间排序
            list = list.stream().sorted(Comparator.comparing(CustomerAbroadDeliveryInfo::getIsDefault).thenComparing(CustomerAbroadDeliveryInfo::getDateUpdated).reversed())
                    .collect(Collectors.toList());
            return beanMapper.mapAsList(list,CustomerAbroadDeliveryInfoVO.class);
        }
        return null;
    }

    @Override
    public List<CustomerAbroadDeliveryInfoVO> effectiveList(String customerName) {
        if(StringUtils.isNotEmpty(customerName)){
            Map<String,Object> params = new LinkedHashMap<String,Object>(){{
                put("customerName",customerName);
            }};
            return customerAbroadDeliveryInfoMapper.effectiveList(params);

        }
        return Lists.newArrayList();
    }

    @Override
    public PageInfo<CustomerAbroadDeliveryInfoVO> pageList(CustomerAbroadDeliveryInfoDTO dto) {
        PageHelper.startPage(dto.getPage(),dto.getLimit());
        Map<String,Object> params = beanMapper.map(dto,Map.class);
        return new PageInfo<>(customerAbroadDeliveryInfoMapper.list(params));
    }

    @Override
    public CustomerAbroadDeliveryInfoVO detail(Long id) {
        CustomerAbroadDeliveryInfo customerDeliveryInfo = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(customerDeliveryInfo),new ServiceException("客户境外收货地址信息不存在"));
        return beanMapper.map(customerDeliveryInfo,CustomerAbroadDeliveryInfoVO.class);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void removeByCustomerId(Long customerId) {
        customerAbroadDeliveryInfoMapper.deleteByExample(Example.builder(CustomerAbroadDeliveryInfo.class).where(TsfWeekendSqls.<CustomerAbroadDeliveryInfo>custom().andEqualTo(false,CustomerAbroadDeliveryInfo::getCustomerId,customerId)).build());
    }

    @Override
    public List<CustomerAbroadDeliveryInfo> list(Long customerId) {
        CustomerAbroadDeliveryInfo condition = new CustomerAbroadDeliveryInfo();
        condition.setCustomerId(customerId);
        return super.list(condition);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteById(Long id) {
        CustomerAbroadDeliveryInfo customerDeliveryInfo = super.getById(id);
        TsfPreconditions.checkArgument(Objects.nonNull(customerDeliveryInfo),new ServiceException("客户境外收货地址信息不存在"));
        super.removeById(id);
    }

    @Override
    public int countByCustomerId(Long customerId) {
        return customerAbroadDeliveryInfoMapper.selectCountByExample(Example.builder(CustomerAbroadDeliveryInfo.class).where(TsfWeekendSqls.<CustomerAbroadDeliveryInfo>custom().andEqualTo(true,CustomerAbroadDeliveryInfo::getCustomerId,customerId)).build());
    }

    @Override
    public PageInfo<CustomerAbroadDeliveryInfo> clientPage(ClientCustomerAbroadDeliveryInfoQTO qto) {
        TsfWeekendSqls sqls = TsfWeekendSqls.<CustomerAbroadDeliveryInfo>custom()
                .andEqualTo(false,CustomerAbroadDeliveryInfo::getCustomerId, SecurityUtil.getCurrentCustomerId())
                .andEqualTo(true,CustomerAbroadDeliveryInfo::getDisabled,qto.getDisabled())
                .andEqualTo(true,CustomerAbroadDeliveryInfo::getIsDefault,qto.getIsDefault());
        return super.pageList(qto.getPage(),qto.getLimit(),sqls,Lists.newArrayList(OrderItem.desc("isDefault"),OrderItem.asc("companyName")));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void clientRemove(Long id) {
        CustomerAbroadDeliveryInfo customerDeliveryInfo = super.getById(id);
        Optional.ofNullable(customerDeliveryInfo).orElseThrow(()->new ServiceException("客户收货信息不存在，请确认是否已经被删除"));
        PermissionUtil.checkClientCustomerPermission(customerDeliveryInfo);
        super.removeById(id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void clientAdd(CustomerAbroadDeliveryInfoDTO dto) {
        CustomerAbroadDeliveryInfo customerDeliveryInfo = beanMapper.map(dto,CustomerAbroadDeliveryInfo.class);
        customerDeliveryInfo.setDisabled(Boolean.FALSE);
        Long customerId = SecurityUtil.getCurrentCustomerId();
        customerDeliveryInfo.setCustomerId(customerId);
        //默认地址信息处理
        if (Objects.equals(Boolean.TRUE, customerDeliveryInfo.getIsDefault())) {
            //需要设置为默认地址，需要取消之前设置的默认地址
            handleOldDefault(SecurityUtil.getCurrentCustomerId());
        }
        super.saveNonNull(customerDeliveryInfo);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void clientEdit(CustomerAbroadDeliveryInfoDTO dto) {
        CustomerAbroadDeliveryInfo oldCustomerDeliveryInfo = super.getById(dto.getId());
        TsfPreconditions.checkArgument(Objects.nonNull(oldCustomerDeliveryInfo),new ServiceException("您选择的数据不存在"));
        CustomerAbroadDeliveryInfo customerDeliveryInfo = beanMapper.map(dto,CustomerAbroadDeliveryInfo.class);
        Long customerId = SecurityUtil.getCurrentCustomerId();
        customerDeliveryInfo.setCustomerId(customerId);
        customerDeliveryInfo.setDateCreated(oldCustomerDeliveryInfo.getDateCreated());
        customerDeliveryInfo.setCreateBy(oldCustomerDeliveryInfo.getCreateBy());
        customerDeliveryInfo.setDisabled(Objects.equals(dto.getDisabled(),Boolean.TRUE));
        customerDeliveryInfo.setIsDefault(Objects.equals(dto.getIsDefault(),Boolean.TRUE));
        //如果由非默认变为默认则需要处理之前设置的默认的
        if (!oldCustomerDeliveryInfo.getIsDefault() && customerDeliveryInfo.getIsDefault()) {
            customerDeliveryInfo.setDisabled(Boolean.FALSE);
            handleOldDefault(customerId);
        }
        super.updateById(customerDeliveryInfo);
    }
}
